/*
 * Copyright (C) 2017
 *
 * Brick Yang <printfxxx@163.com>
 *
 * This program is free software. You can redistribute it and/or
 * modify it as you like.
 */

/**
 * @file	dpni.h
 * @brief	Header file for dpni driver
 */

#ifndef _DPNI_H_
#define _DPNI_H_

#include <linux/types.h>
#include <linux/fsl/mc.h>

#define DPNI_MAX_DPBP	8

struct dpni_pools_cfg {
	u8 num_dpbp;
	struct {
		int dpbp_id;
		u16 buffer_size;
		int backup_pool;
	} pools[DPNI_MAX_DPBP];
};

struct dpni_attr {
	u32 options;
	u8 num_queues;
	u8 num_tcs;
	u8 mac_filter_entries;
	u8 vlan_filter_entries;
	u8 qos_entries;
	u16 fs_entries;
	u8 qos_key_size;
	u8 fs_key_size;
	u16 wriop_version;
};

enum dpni_error_action {
	DPNI_ERROR_ACTION_DISCARD = 0,
	DPNI_ERROR_ACTION_CONTINUE = 1,
	DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2,
};

struct dpni_error_cfg {
	u32 errors;
#define DPNI_ERROR_EOFHE	0x00020000
#define DPNI_ERROR_FLE		0x00002000
#define DPNI_ERROR_FPE		0x00001000
#define DPNI_ERROR_PHE		0x00000020
#define DPNI_ERROR_L3CE		0x00000004
#define DPNI_ERROR_L4CE		0x00000001
	enum dpni_error_action error_action;
	int set_frame_annotation;
};

enum dpni_queue_type {
	DPNI_QUEUE_RX,
	DPNI_QUEUE_TX,
	DPNI_QUEUE_TX_CONFIRM,
	DPNI_QUEUE_RX_ERR,
};

struct dpni_buffer_layout {
	u32 options;
#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP		0x00000001
#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT	0x00000002
#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS	0x00000004
#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE	0x00000008
#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN		0x00000010
#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM	0x00000020
#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM	0x00000040
	int pass_timestamp;
	int pass_parser_result;
	int pass_frame_status;
	u16 private_data_size;
	u16 data_align;
	u16 data_head_room;
	u16 data_tail_room;
};

#define DPNI_STATISTICS_CNT	7

union dpni_statistics {
	struct {
		u64 ingress_all_frames;
		u64 ingress_all_bytes;
		u64 ingress_multicast_frames;
		u64 ingress_multicast_bytes;
		u64 ingress_broadcast_frames;
		u64 ingress_broadcast_bytes;
	} page_0;
	struct {
		u64 egress_all_frames;
		u64 egress_all_bytes;
		u64 egress_multicast_frames;
		u64 egress_multicast_bytes;
		u64 egress_broadcast_frames;
		u64 egress_broadcast_bytes;
	} page_1;
	struct {
		u64 ingress_filtered_frames;
		u64 ingress_discarded_frames;
		u64 ingress_nobuffer_discards;
		u64 egress_discarded_frames;
		u64 egress_confirmed_frames;
	} page_2;
	struct {
		u64 counter[DPNI_STATISTICS_CNT];
	} raw;
};

struct dpni_link_cfg {
	u32 rate;
	u64 options;
#define DPNI_LINK_OPT_AUTONEG		0x0000000000000001ULL
#define DPNI_LINK_OPT_HALF_DUPLEX	0x0000000000000002ULL
#define DPNI_LINK_OPT_PAUSE		0x0000000000000004ULL
#define DPNI_LINK_OPT_ASYM_PAUSE	0x0000000000000008ULL
#define DPNI_LINK_OPT_PFC_PAUSE		0x0000000000000010ULL
	u64 advertising;
};

struct dpni_link_state {
	u32 rate;
	u64 options;
	int up;
	int state_valid;
	u64 supported;
	u64 advertising;
};

enum dpni_confirmation_mode {
	DPNI_CONF_AFFINE,
	DPNI_CONF_SINGLE,
	DPNI_CONF_DISABLE,
};

enum dpni_dest {
	DPNI_DEST_NONE = 0,
	DPNI_DEST_DPIO = 1,
	DPNI_DEST_DPCON = 2,
};

struct dpni_queue {
	struct {
		u16 id;
		enum dpni_dest type;
		char hold_active;
		u8 priority;
	} destination;
	u64 user_context;
	struct {
		u64 value;
		char stash_control;
	} flc;
};

struct dpni_queue_id {
	u32 fqid;
	u16 qdbin;
};

struct dpni_port_cfg {
	int loopback_en;
};

int dpni_open(struct fsl_mc_io *mc_io,
	      u32 cmd_flags,
	      int dpni_id,
	      u16 *token);

int dpni_close(struct fsl_mc_io *mc_io,
	       u32 cmd_flags,
	       u16 token);

int dpni_set_pools(struct fsl_mc_io *mc_io,
		   u32 cmd_flags,
		   u16 token,
		   const struct dpni_pools_cfg *cfg);

int dpni_enable(struct fsl_mc_io *mc_io,
		u32 cmd_flags,
		u16 token);

int dpni_disable(struct fsl_mc_io *mc_io,
		 u32 cmd_flags,
		 u16 token);

int dpni_is_enabled(struct fsl_mc_io *mc_io,
		    u32 cmd_flags,
		    u16 token,
		    int *en);

int dpni_reset(struct fsl_mc_io *mc_io,
	       u32 cmd_flags,
	       u16 token);

int dpni_get_attributes(struct fsl_mc_io *mc_io,
			u32 cmd_flags,
			u16 token,
			struct dpni_attr *attr);

int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
			     u32 cmd_flags,
			     u16 token,
			     struct dpni_error_cfg *cfg);

int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
			   u32 cmd_flags,
			   u16 token,
			   enum dpni_queue_type qtype,
			   const struct dpni_buffer_layout *layout);

int dpni_get_statistics(struct fsl_mc_io *mc_io,
			u32 cmd_flags,
			u16 token,
			u8 page,
			union dpni_statistics *stat);

int dpni_reset_statistics(struct fsl_mc_io *mc_io,
			  u32 cmd_flags,
			  u16 token);

int dpni_get_link_cfg(struct fsl_mc_io *mc_io,
		      u32 cmd_flags,
		      u16 token,
		      struct dpni_link_cfg *cfg);

int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
		      u32 cmd_flags,
		      u16 token,
		      const struct dpni_link_cfg *cfg);

int dpni_set_link_cfg_v2(struct fsl_mc_io *mc_io,
			 u32 cmd_flags,
			 u16 token,
			 const struct dpni_link_cfg *cfg);

int dpni_get_link_state(struct fsl_mc_io *mc_io,
			u32 cmd_flags,
			u16 token,
			struct dpni_link_state *state);

int dpni_get_link_state_v2(struct fsl_mc_io *mc_io,
			   u32 cmd_flags,
			   u16 token,
			   struct dpni_link_state *state);

int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
			      u32 cmd_flags,
			      u16 token,
			      u16 max_frame_length);

int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io,
			       u32 cmd_flags,
			       u16 token,
			       int en);

int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
			     u32 cmd_flags,
			     u16 token,
			     int en);

int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
				  u32 cmd_flags,
				  u16 token,
				  enum dpni_confirmation_mode mode);

int dpni_set_queue(struct fsl_mc_io *mc_io,
		   u32 cmd_flags,
		   u16 token,
		   enum dpni_queue_type qtype,
		   u8 tc,
		   u8 index,
		   u8 options,
#define DPNI_QUEUE_OPT_USER_CTX		0x00000001
#define DPNI_QUEUE_OPT_DEST		0x00000002
#define DPNI_QUEUE_OPT_FLC		0x00000004
#define DPNI_QUEUE_OPT_HOLD_ACTIVE	0x00000008
		   const struct dpni_queue *queue);

int dpni_get_queue(struct fsl_mc_io *mc_io,
		   u32 cmd_flags,
		   u16 token,
		   enum dpni_queue_type qtype,
		   u8 tc,
		   u8 index,
		   struct dpni_queue *queue,
		   struct dpni_queue_id *qid);

int dpni_set_port_cfg(struct fsl_mc_io *mc_io,
		      u32 cmd_flags,
		      u16 token,
		      u32 flags,
#define DPNI_PORT_CFG_LOOPBACK		0x01
		      struct dpni_port_cfg *port_cfg);

int dpni_get_port_cfg(struct fsl_mc_io *mc_io,
		      u32 cmd_flags,
		      u16 token,
		      u32 flags,
		      struct dpni_port_cfg *port_cfg);

#endif	/* _DPNI_H_ */
